#include "widget.h"
#include "./ui_widget.h"
#include <QKeyEvent>  // 确保包含实际定义的头文件
#include <QTimer>
#include"bullet.h"
#include<QRandomGenerator>
#include<QMessageBox>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    setFocusPolicy(Qt::StrongFocus);  // 允许接收键盘事件
    setFocus();                       // 主动获取焦点

    // mygameview.setSceneRect(QRect(0,0,1870,633));
    // mscene.setSceneRect(QRect(0,0,1870,633));存在窗口与视图不匹配的问题

    QRect sceneRect(0, 0, 1870, 633);
    mygameview.setSceneRect(sceneRect);
    mscene.setSceneRect(sceneRect);

    mybg1.setPixmap(QPixmap(":/img/bg.png"));
    mcar.setPixmap(QPixmap(":/img/car.png"));        // 传递对象而非字符串
    mcar.setScale(0.6);//调整车大小

    mscene.addItem(&mybg1);//图片添加到场景

    mscene.addItem(&mcar);//图片添加到场景

    mygameview.setScene(&mscene);//设置视图的场景

    mygameview.setParent(this);
    mygameview.show();

    //开启车移动定时器
    carmovetimer=new QTimer(this);
    carmovetimer->start(10);
    connect(carmovetimer,&QTimer::timeout,this,&Widget::carmove);
    //开启子弹发射定时器
    mcarshoottimer=new QTimer(this);
    mcarshoottimer->start(mcar.shootcircle);
    connect(mcarshoottimer,&QTimer::timeout,this,&Widget::mcarbulletshoot);
    //开启子弹移动定时器
    bulletmovetimer=new QTimer(this);
    bulletmovetimer->start(10);
    connect(bulletmovetimer,&QTimer::timeout,[this](){//[]内要显式捕获当前对象的指针
        for(auto bullet : bulletlist){
            bullet->bulletmove();
        }
    });

    //开启敌人创建定时器
    enemycreatedtimer=new QTimer(this);
    enemycreatedtimer->start(300);
    connect(enemycreatedtimer,&QTimer::timeout,this,&Widget::createenemy);

    // 在 Widget 构造函数中新增定时器
    QTimer *collisionTimer = new QTimer(this);
    collisionTimer->start(20); // 每20ms检测一次
    connect(collisionTimer, &QTimer::timeout, this, &Widget::collision);
}

//碰撞检测
void Widget::collision(){
    QList<bullet*> bulletremoved;
    QList<enemy*> enemyremoved;

    for(int i=0;i<bulletlist.size();i++){
        for(int j=0;j<enemylist.size();j++){//每一个子弹和每一个敌人碰撞
            if(bulletlist[i]->collidesWithItem(enemylist[j])){
          /*      //场景中移除(先)因为需要使用列表
                mscene.removeItem(bulletlist[i]);
                mscene.removeItem(enemylist[j]);
                //列表中也要移除
                bulletlist.removeOne(bulletlist[i]);
                enemylist.removeOne(enemylist[j]);
           不可如此，因为一碰撞就马上删除会使之后遍历时下标出错直接闪退
         */


                bulletremoved.append(bulletlist[i]);
               enemyremoved.append(enemylist[j]);
            }
        }


    }

    // 移除标记的子弹
    for (bullet* b : bulletremoved) {
        mscene.removeItem(b);
        bulletlist.removeOne(b);
        delete b;
    }

    // 移除标记的敌人
    for (enemy* e : enemyremoved) {
        mscene.removeItem(e);
        enemylist.removeOne(e);
        delete e;
    }


    //enemy碰到跑车游戏结束
    for (enemy* e : enemylist) {
        if (e->collidesWithItem(&mcar)) {
            die();
            return; // 立即返回，避免后续操作
        }
    }
}

void Widget::die()
{
    // 停止所有定时器
    carmovetimer->stop();
    mcarshoottimer->stop();
    bulletmovetimer->stop();
    enemycreatedtimer->stop();

    QList<enemy*> enemiesToRemove = enemylist; //单独建立副本，最后统一清理
    for (enemy* e : enemiesToRemove) {
        // 从场景中移除enemy
        if (e->scene()) {
            mscene.removeItem(e);
        }
        // 从列表中移除
        enemylist.removeOne(e);
        // 删除对象（触发enemy析构函数）
        delete e;
    }

    QList<bullet*> bulletsToRemove = bulletlist;//单独建立副本，最后统一清理
    for (bullet* b : bulletsToRemove) {
        if (b->scene()) {
            mscene.removeItem(b);
        }
        bulletlist.removeOne(b);
        delete b;
    }

    // 显示游戏结束信息
    QMessageBox::information(this, " ", "你被死侍击杀了");

    // 关闭游戏窗口
    close();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::keyPressEvent(QKeyEvent *event)
{
    switch(event->key()){
    case Qt::Key_W:
    case Qt::Key_A:
    case Qt::Key_S:
    case Qt::Key_D:
        mkeylist.append(event->key());//把按下的全存入，才能斜着移动
        break;
    }



    // switch(event->key()){
    // case Qt::Key_W:
    //     mcar.moveBy(0,-5);//正为向下
    //     break;
    // case Qt::Key_A:
    //     mcar.moveBy(-5,0);
    //     break;
    // case Qt::Key_S:
    //     mcar.moveBy(0,5);
    //     break;
    // case Qt::Key_D:
    //     mcar.moveBy(5,0);
    //     break;

    // }
}

void Widget::keyReleaseEvent(QKeyEvent *event)
{
    //移除对应按键组合
    if(mkeylist.contains(event->key())){

        mkeylist.removeOne(event->key());
    }
}

void Widget::carmove()
{
    for (int keycode:mkeylist) {
        switch(keycode){
        case Qt::Key_W:
            mcar.moveBy(0,-5);//正为向下
            break;
        case Qt::Key_A:
            mcar.moveBy(-5,0);
            break;
        case Qt::Key_S:
            mcar.moveBy(0,5);
            break;
        case Qt::Key_D:
            mcar.moveBy(5,0);
            break;
        }
    }
    //车出界判断
    if(mcar.x()<0){
        mcar.setX(0);
    }
    if(mcar.y()<0){
        mcar.setY(0);
    }
    if(mcar.x()>this->width()-mcar.pixmap().width()){//车图片左上角x坐标大于窗口宽度减去车图片宽度
        mcar.setX(this->width()-mcar.pixmap().width());
    }
    if(mcar.y()>this->height()-mcar.pixmap().height()){
        mcar.setY(this->height()-mcar.pixmap().height());
    }
}

void Widget::mcarbulletshoot()//子弹创建函数
{
    QPixmap bulletimg(":/img/bulletpicture.png");
    QPoint pos(mcar.x()+mcar.pixmap().width()*0.6,mcar.y()-mcar.pixmap().height()*0.6/2+bulletimg.height()/2-10);//让子弹出现在跑车正前方，再上调一点，*0.6因为我之前把跑车缩放到了0.6

    bullet* mbullet=new bullet(pos,bulletimg,bullet::player);
    //加到场景中
    mscene.addItem(mbullet);
    bulletlist.append(mbullet);//添加生成的bullet到bulletlist中
}


void Widget::createenemy()
{
    // 随机位置生成
    int enemyposy = QRandomGenerator::global()->bounded(height() - frameheight);//从0到最大值生成随机数
    QPoint spawnPos(this->width(),enemyposy);

    // 创建敌人实例
    enemy* Enemy = new enemy(spawnPos,spritepath,framewidth,frameheight, framenum,frameupdatespeed);

    connect(Enemy, &enemy::destroyed, this, [this](enemy* e) {
        enemylist.removeOne(e); // 从列表移除
    });
    // 添加到场景和列表
    mscene.addItem(Enemy);
    enemylist.append(Enemy);
}
/*
 出现了libc++abi: Pure virtual function called!问题
需要在敌人被击杀或者出界销毁后安全地被销毁
如出界以后发出销毁信号，然后在创建敌人对象的函数中将信号与槽连接，进行销毁操作
*/
